﻿using System;
using System.Collections.Generic;
using System.Drawing.Imaging;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.IO.MemoryMappedFiles;
using System.Buffers;
using System.Diagnostics;
using System.Runtime.InteropServices;
using iTextSharp.text.pdf;
using System.Drawing.Drawing2D;

namespace SignetKA.utils
{
    internal class ImageTool
    {
        public static Bitmap ConvertImage(iTextSharp.text.Image img)
        {
            var a = img.IsImgRaw();
            byte[] imageBytes = img.OriginalData;
            using (MemoryStream ms = new MemoryStream(imageBytes))
            using (System.Drawing.Image img2 = System.Drawing.Image.FromStream(ms))
            {
                Bitmap bitmap = new Bitmap(img2);
                //进行后续处理，注意要处理异常和资源释放
                return bitmap;
            }
        }
        public static Bitmap BlendImagesParallel(Bitmap baseImage, Bitmap overlayImage, float opacity)
        {
            if (opacity < 0 || opacity > 1) opacity = 1;
            if (baseImage.Size != overlayImage.Size)
            {
                overlayImage = new Bitmap(overlayImage, baseImage.Size);
            }

            Bitmap resultImage = new Bitmap(baseImage.Width, baseImage.Height, PixelFormat.Format32bppArgb);

            var baseData = baseImage.LockBits(
                new Rectangle(0, 0, baseImage.Width, baseImage.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);

            var overlayData = overlayImage.LockBits(
                new Rectangle(0, 0, overlayImage.Width, overlayImage.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb);

            var resultData = resultImage.LockBits(
                new Rectangle(0, 0, resultImage.Width, resultImage.Height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb);

            unsafe
            {
                byte* basePtr = (byte*)baseData.Scan0;
                byte* overlayPtr = (byte*)overlayData.Scan0;
                byte* resultPtr = (byte*)resultData.Scan0;

                int bytesPerPixel = 4;
                int stride = baseData.Stride;
                int width = baseImage.Width;
                int height = baseImage.Height;

                Parallel.For(0, height, y =>
                {
                    int yIndex = y * stride;
                    for (int x = 0; x < width; x++)
                    {
                        int index = yIndex + x * bytesPerPixel;

                        Color baseColor = Color.FromArgb(
                            basePtr[index + 3],
                            basePtr[index + 2],
                            basePtr[index + 1],
                            basePtr[index]);

                        Color overlayColor = Color.FromArgb(
                            overlayPtr[index + 3],
                            overlayPtr[index + 2],
                            overlayPtr[index + 1],
                            overlayPtr[index]);

                        float combinedAlpha = overlayColor.A / 255f * opacity +
                                            baseColor.A / 255f * (1 - overlayColor.A / 255f * opacity);

                        float blendRatio = (overlayColor.A / 255f) * opacity / combinedAlpha;

                        resultPtr[index] = (byte)(overlayColor.B * blendRatio + baseColor.B * (1 - blendRatio));
                        resultPtr[index + 1] = (byte)(overlayColor.G * blendRatio + baseColor.G * (1 - blendRatio));
                        resultPtr[index + 2] = (byte)(overlayColor.R * blendRatio + baseColor.R * (1 - blendRatio));
                        resultPtr[index + 3] = (byte)(baseColor.A);
                    }
                });
            }

            baseImage.UnlockBits(baseData);
            overlayImage.UnlockBits(overlayData);
            resultImage.UnlockBits(resultData);

            return resultImage;
        }

        public static Bitmap ScaleByPercentage(Bitmap original, float percentage, bool keepAspectRatio = true)
        {
            if (percentage <= 0 || percentage > 1000)
                throw new ArgumentException("Invalid percentage value (0-1000).");

            float scaleFactor = percentage / 100f;
            int newWidth, newHeight;

            if (keepAspectRatio)
            {
                // 保持比例时直接等比缩放
                newWidth = (int)(original.Width * scaleFactor);
                newHeight = (int)(original.Height * scaleFactor);
            }
            else
            {
                // 允许拉伸/压缩宽高
                newWidth = (int)(original.Width * scaleFactor);
                newHeight = (int)(original.Height * scaleFactor);
            }

            var scaledBitmap = new Bitmap(newWidth, newHeight);

            using (var graphics = Graphics.FromImage(scaledBitmap))
            {
                graphics.InterpolationMode = InterpolationMode.HighQualityBilinear;
                graphics.DrawImage(
                    original,
                    new RectangleF(0, 0, newWidth, newHeight),
                    new RectangleF(0, 0, original.Width, original.Height),
                    GraphicsUnit.Pixel
                );
            }

            return scaledBitmap;
        }
        public static Bitmap CropImage(Bitmap source, float x, float y, float width, float height)
        {
            // 参数验证
            if (source == null)
                throw new ArgumentNullException(nameof(source));
            //if (x < 0 || y < 0 || width <= 0 || height <= 0)
            //    throw new ArgumentOutOfRangeException("区域参数必须为正数");
            //if (x + width > source.Width || y + height > source.Height)
            //    throw new ArgumentException("截取区域超出原图范围");

            // 创建目标位图
            Bitmap result = new Bitmap((int)width, (int)height, source.PixelFormat);
            result.SetResolution(source.HorizontalResolution, source.VerticalResolution);

            // 使用高质量绘图参数
            using (Graphics g = Graphics.FromImage(result))
            {
                g.CompositingQuality = CompositingQuality.HighQuality;
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.SmoothingMode = SmoothingMode.HighQuality;

                // 定义源区域和目标区域
                RectangleF srcRect = new RectangleF(x, y, width, height);
                RectangleF destRect = new RectangleF(0, 0, width, height);

                // 执行绘图操作
                g.DrawImage(source, destRect, srcRect, GraphicsUnit.Pixel);
            }

            return result;
        }
        public static Bitmap CropWithDpiParallel(
        Bitmap source,
        float sourceDpi,
        RectangleF physicalCropRectMM,
        float targetDpi)
        {
            if (source.PixelFormat != PixelFormat.Format32bppArgb)
                throw new ArgumentException("仅支持Format32bppArgb格式");

            // 转换物理坐标为像素区域（预先校验确保区域合法）
            var sourceRect = ConvertToSourcePixels(source, physicalCropRectMM, sourceDpi);
            var targetSize = CalculateTargetSize(physicalCropRectMM, targetDpi);
            var source_w = source.Width;
            var cropped = new Bitmap(targetSize.Width, targetSize.Height, PixelFormat.Format32bppArgb);
            cropped.SetResolution(targetDpi, targetDpi);

            var sourceData = source.LockBits(new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
            var targetData = cropped.LockBits(new Rectangle(0, 0, cropped.Width, cropped.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            try 
            {
                unsafe
                {
                    byte* srcPtr = (byte*)sourceData.Scan0;
                    byte* dstPtr = (byte*)targetData.Scan0;

                    int srcStride = sourceData.Stride;
                    int dstStride = targetData.Stride;
                    int bytesPerPixel = 4; // Format32bppArgb

                    // 预计算缩放比例，避免循环内重复计算除法
                    float scaleX = (float)sourceRect.Width / targetSize.Width;
                    float scaleY = (float)sourceRect.Height / targetSize.Height;

                    // 并行处理行（内核优化：行级分割）
                    Parallel.For(0, targetSize.Height, ty =>
                    {
                        // 计算源坐标行（batchBlock为缓存行以提高连续性）
                        int srcYBase = (int)(ty * scaleY) + sourceRect.Y;
                        byte* srcRow = srcPtr + srcYBase * srcStride;
                        byte* dstRow = dstPtr + ty * dstStride;

                        //【优化】：将内层循环转化为整块内存复制（当scaleX接近1时跳过插值）
                        if (Math.Abs(scaleX - 1) < 0.001f)
                        {
                            // 直接内存拷贝（无缩放）
                            int copyBytes = bytesPerPixel * targetSize.Width;
                            Buffer.MemoryCopy(
                                srcRow + sourceRect.X * bytesPerPixel,
                                dstRow,
                                copyBytes,
                                copyBytes
                            );
                        }
                        else
                        {
                            // 按比例逐像素复制（允许简单插值）
                            for (int tx = 0; tx < targetSize.Width; tx++)
                            {
                                int srcX = (int)(tx * scaleX) + sourceRect.X;
                                if (srcX >= source_w) srcX = source_w - 1;
                                if (srcX < 0) srcX = 0;

                                var srcPixel = srcRow + srcX * bytesPerPixel;
                                var dstPixel = dstRow + tx * bytesPerPixel;

                                // 拷贝32位像素（等同于循环4次byte复制，但直接用int指针操作更快）
                                *(int*)dstPixel = *(int*)srcPixel;
                            }
                        }
                    });
                }
            }
            finally
            {
                source.UnlockBits(sourceData);
                cropped.UnlockBits(targetData);
            }

            return cropped;
        }

        // 辅助方法：将物理坐标转换至源图的像素区域（简化）
        private static Rectangle ConvertToSourcePixels(Bitmap source, RectangleF physicalRectMM, float dpi)
        {
            float pixelsPerMM = dpi / 25.4f;
            int x = (int)(physicalRectMM.X * pixelsPerMM);
            int y = (int)(physicalRectMM.Y * pixelsPerMM);
            int width = (int)(physicalRectMM.Width * pixelsPerMM);
            int height = (int)(physicalRectMM.Height * pixelsPerMM);

            x = Clamp(x, 0, source.Width - 1);
            y = Clamp(y, 0, source.Height - 1);
            width = Clamp(width, 1, source.Width - x);
            height = Clamp(height, 1, source.Height - y);

            return new Rectangle(x, y, width, height);
        }
        public static int Clamp(int value, int min, int max)
        {
            return (value < min) ? min : (value > max) ? max : value;
        }

        public static float Clamp(float value, float min, float max)
        {
            // 处理浮点数 NaN 的情况（与官方行为一致）
            if (float.IsNaN(value)) return float.NaN;
            return (value < min) ? min : (value > max) ? max : value;
        }
        private static Size CalculateTargetSize(RectangleF physicalRectMM, float targetDpi)
        {
            float pixelsPerMM = targetDpi / 25.4f;
            int width = (int)(physicalRectMM.Width * pixelsPerMM);
            int height = (int)(physicalRectMM.Height * pixelsPerMM);
            return new Size(width, height);
        }

        public static Bitmap MultiplyBitmaps(Bitmap source1, Bitmap source2)
        {
            if (source1.Size != source2.Size)
                throw new ArgumentException("图像尺寸必须相同！");

            Bitmap output = new Bitmap(source1.Width, source1.Height);

            // 锁定位图数据以提高性能
            BitmapData data1 = source1.LockBits(
                new Rectangle(0, 0, source1.Width, source1.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb
            );

            BitmapData data2 = source2.LockBits(
                new Rectangle(0, 0, source2.Width, source2.Height),
                ImageLockMode.ReadOnly,
                PixelFormat.Format32bppArgb
            );

            BitmapData outputData = output.LockBits(
                new Rectangle(0, 0, output.Width, output.Height),
                ImageLockMode.WriteOnly,
                PixelFormat.Format32bppArgb
            );

            unsafe
            {
                byte* ptr1 = (byte*)data1.Scan0;
                byte* ptr2 = (byte*)data2.Scan0;
                byte* outPtr = (byte*)outputData.Scan0;

                int bytesPerPixel = 4; // 32bppArgb 每个像素占4字节（B, G, R, A）

                for (int y = 0; y < source1.Height; y++)
                {
                    for (int x = 0; x < source1.Width; x++)
                    {
                        if (ptr1[3] == 255)
                        {
                            // 示例仅处理 RGB，忽略 Alpha 通道（需根据需求修改）
                            outPtr[0] = (byte)((ptr1[0] * ptr2[0] / 255)); // B
                            outPtr[1] = (byte)((ptr1[1] * ptr2[1] / 255)); // G
                            outPtr[2] = (byte)((ptr1[2] * ptr2[2] / 255)); // R
                        }
                        else
                        {
                            // 示例仅处理 RGB，忽略 Alpha 通道（需根据需求修改）
                            outPtr[0] = (byte)((ptr1[0] * ptr2[0] / 255)); // B
                            outPtr[1] = (byte)((ptr1[1] * ptr2[1] / 255)); // G
                            outPtr[2] = (byte)((ptr1[2] * ptr2[2] / 255)); // R
                        }
                        outPtr[3] = 255; // Alpha 固定为不透明

                        ptr1 += bytesPerPixel;
                        ptr2 += bytesPerPixel;
                        outPtr += bytesPerPixel;
                    }
                }
            }

            // 解锁内存区域
            source1.UnlockBits(data1);
            source2.UnlockBits(data2);
            output.UnlockBits(outputData);

            return output;
        }

    }
}
